#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    mockMouse=false;
    m_gamepad=nullptr;

    mouseMoveOffset=4;
    ui->slider->setValue(mouseMoveOffset);
    ui->slider->setEnabled(mockMouse);

    g_width=QGuiApplication::primaryScreen()->size().width();
    g_height=QGuiApplication::primaryScreen()->size().height();

    m_manager=QGamepadManager::instance();
    detectController();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::detectController()
{
    auto gamepads = m_manager->connectedGamepads();
    if(gamepads.isEmpty())
    {
        ui->statusbar->showMessage("Did not find any connected gamepads",6000);
        return;
    }

    foreach (auto index, gamepads) {
        ui->items->addItem(m_manager->gamepadName(index));
    }
    m_gamepad=new QGamepad(gamepads.first(),this);
    processAction();
}

void MainWindow::append(const QString &action)
{
    ui->textBrowser->append(action);
}

void MainWindow::processAction()
{
    connect(m_gamepad, &QGamepad::axisLeftXChanged,  this, &MainWindow::onAxisLeftXChanged);
    connect(m_gamepad, &QGamepad::axisLeftYChanged,  this, &MainWindow::onAxisLeftYChanged);
    connect(m_gamepad, &QGamepad::axisRightXChanged, this, &MainWindow::onAxisRightXChanged);
    connect(m_gamepad, &QGamepad::axisRightYChanged, this, &MainWindow::onAxisRightYChanged);

    connect(m_gamepad, &QGamepad::buttonAChanged, this, &MainWindow::onButtonAChanged);
    connect(m_gamepad, &QGamepad::buttonBChanged, this, &MainWindow::onButtonBChanged);
    connect(m_gamepad, &QGamepad::buttonXChanged, this, &MainWindow::onButtonXChanged);
    connect(m_gamepad, &QGamepad::buttonYChanged, this, &MainWindow::onButtonYChanged);

    connect(m_gamepad, &QGamepad::buttonL1Changed, this, &MainWindow::onButtonL1Changed);
    connect(m_gamepad, &QGamepad::buttonL2Changed, this, &MainWindow::onButtonL2Changed);
    connect(m_gamepad, &QGamepad::buttonL3Changed, this, &MainWindow::onButtonL3Changed);
    connect(m_gamepad, &QGamepad::buttonR1Changed, this, &MainWindow::onButtonR1Changed);
    connect(m_gamepad, &QGamepad::buttonR2Changed, this, &MainWindow::onButtonR2Changed);
    connect(m_gamepad, &QGamepad::buttonR3Changed, this, &MainWindow::onButtonR3Changed);

    connect(m_gamepad, &QGamepad::buttonUpChanged, this, &MainWindow::onButtonUpChanged);
    connect(m_gamepad, &QGamepad::buttonDownChanged, this, &MainWindow::onButtonDownChanged);
    connect(m_gamepad, &QGamepad::buttonLeftChanged, this, &MainWindow::onButtonLeftChanged);
    connect(m_gamepad, &QGamepad::buttonRightChanged, this, &MainWindow::onButtonRightChanged);

    connect(m_gamepad, &QGamepad::buttonSelectChanged, this, &MainWindow::onButtonSelectChanged);
    connect(m_gamepad, &QGamepad::buttonStartChanged, this, &MainWindow::onButtonStartChanged);
    connect(m_gamepad, &QGamepad::buttonGuideChanged, this, &MainWindow::onButtonGuideChanged);
    connect(m_gamepad, &QGamepad::buttonCenterChanged, this, &MainWindow::onButtonCenterChanged);

    connect(m_gamepad, &QGamepad::connectedChanged, this, &MainWindow::onConnectedChanged);

    /*
    connect(m_gamepad, &QGamepad::axisLeftXChanged, this, [&](double value){
        append(QString("Left X, %1").arg(value));
    });
    connect(m_gamepad, &QGamepad::axisLeftYChanged, this, [&](double value){
        append(QString("Left Y, %1").arg(value));
    });
    connect(m_gamepad, &QGamepad::axisRightXChanged, this, [&](double value){
        append(QString("Right X, %1").arg(value));
    });
    connect(m_gamepad, &QGamepad::axisRightYChanged, this, [&](double value){
        append(QString("Right Y, %1").arg(value));
    });
    */
}

void MainWindow::onAxisLeftXChanged(double value)
{
    if(!mockMouse)
        append(QString("Left X, %1").arg(value));
    else
    {
        QPoint pos=QCursor::pos();
        if(value > 0.0)
        {
            QCursor::setPos(pos.x() + 4,pos.y());
        }
        else if(value < 0.0)
        {
            QCursor::setPos(pos.x() - 4,pos.y());
        }
    }
}

void MainWindow::onAxisLeftYChanged(double value)
{
    if(!mockMouse)
        append(QString("Left Y, %1").arg(value));
    else
    {
        QPoint pos=QCursor::pos();
        if(value > 0.0)
        {
            QCursor::setPos(pos.x(),pos.y() + 4);
        }
        else if(value < 0.0)
        {
            QCursor::setPos(pos.x(),pos.y() - 4);
        }
    }
}

void MainWindow::onAxisRightXChanged(double value)
{
    if(!mockMouse)
        append(QString("Right X, %1").arg(value));
    else
    {
        QPoint pos=QCursor::pos();
        if(value > 0.0)
        {
            QCursor::setPos(pos.x() + mouseMoveOffset,pos.y());
        }
        else if(value < 0.0)
        {
            QCursor::setPos(pos.x() - mouseMoveOffset,pos.y());
        }
    }

}

void MainWindow::onAxisRightYChanged(double value)
{
    if(!mockMouse)
        append(QString("Right Y, %1").arg(value));
    else
    {
        QPoint pos=QCursor::pos();
        if(value > 0.0)
        {
            QCursor::setPos(pos.x(),pos.y() + mouseMoveOffset);
        }
        else if(value < 0.0)
        {
            QCursor::setPos(pos.x(),pos.y() - mouseMoveOffset);
        }
    }
}

void MainWindow::onButtonAChanged(bool pressed)
{
    if(pressed)
    {
        if(!mockMouse)
            append(QString("Button A, %1").arg(A_PRESSED));
    }
    else {
        QPoint pos=QCursor::pos();
        mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,pos.x(), pos.y(), 0, 0);
        mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,pos.x(), pos.y(), 0, 0);
    }
}

void MainWindow::onButtonBChanged(bool pressed)
{
    if(pressed)
    {
        if(!mockMouse)
            append(QString("Button B, %1").arg(A_PRESSED));
        else
        {
            QPoint pos=QCursor::pos();
            mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTDOWN,pos.x(), pos.y(), 0, 0);
            mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTUP,pos.x(), pos.y(), 0, 0);
        }
    }
}
void MainWindow::onButtonXChanged(bool pressed)
{
    if(pressed)
        append(QString("Button X, %1").arg(A_PRESSED));
}

void MainWindow::onButtonYChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Y, %1").arg(A_PRESSED));
}

void MainWindow::onButtonL1Changed(bool pressed)
{
    if(pressed)
        append(QString("Button L1, %1").arg(A_PRESSED));
}

void MainWindow::onButtonL2Changed(double value)
{
    if(value == 1.0)
        append(QString("Button L2, %1").arg(A_PRESSED));
}

void MainWindow::onButtonL3Changed(bool pressed)
{
    if(pressed)
        append(QString("Button L3, %1").arg(A_PRESSED));
}

void MainWindow::onButtonR1Changed(bool pressed)
{
    if(pressed)
        append(QString("Button R1, %1").arg(A_PRESSED));
}

void MainWindow::onButtonR2Changed(double value)
{
    if(value == 1.0)
        append(QString("Button R2, %1").arg(A_PRESSED));
}

void MainWindow::onButtonR3Changed(bool pressed)
{
    if(pressed)
        append(QString("Button R3, %1").arg(A_PRESSED));
}

void MainWindow::onButtonUpChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Up, %1").arg(A_PRESSED));
}

void MainWindow::onButtonDownChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Down, %1").arg(A_PRESSED));
}

void MainWindow::onButtonLeftChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Left, %1").arg(A_PRESSED));
}

void MainWindow::onButtonRightChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Right, %1").arg(A_PRESSED));
}

void MainWindow::onButtonSelectChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Select, %1").arg(A_PRESSED));
}

void MainWindow::onButtonStartChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Start, %1").arg(A_PRESSED));
}

void MainWindow::onButtonGuideChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Guide, %1").arg(A_PRESSED));
}

void MainWindow::onButtonCenterChanged(bool pressed)
{
    if(pressed)
        append(QString("Button Center, %1").arg(A_PRESSED));
}

void MainWindow::onConnectedChanged(bool connected)
{
    QString keyAction = (connected)?A_CONNECTED:B_DISCONNECTED;
    append(QString("Gamepad, %1").arg(keyAction));
}

void MainWindow::on_mockMouse_stateChanged(int state)
{
    if(state==Qt::Checked)
        mockMouse=true;
    else
        mockMouse=false;
    ui->slider->setEnabled(mockMouse);
}

void MainWindow::on_slider_valueChanged(int value)
{
    mouseMoveOffset=value;
}
